home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / pascal / gsdbloo.exe / GS_DBNTX.PAS < prev    next >
Pascal/Delphi Source File  |  1992-02-26  |  55KB  |  1,304 lines

  1. unit GS_DBNtx;
  2. {-----------------------------------------------------------------------------
  3.                            Clipper Index Handler
  4.  
  5.        GS_DBNtx Copyright (c)  Richard F. Griffin
  6.  
  7.        4 August 1991
  8.  
  9.        102 Molded Stone Pl
  10.        Warner Robins, GA  31088
  11.  
  12.        -------------------------------------------------------------
  13.        This unit handles the objects for all Clipper index (.NTX)
  14.        operations.  This unit may be implemented by changing the
  15.        GS_DBASE.PAS unit's USES statement from GS_DBNDX to GS_DBNTX.
  16.        That's the only change necessary to replace .NDX indexes with
  17.        Clipper .NTX indexes.
  18.  
  19.        changes:
  20.  
  21.           02 Feb 92 - Added call to KeyLocRec in main part of KeyUpdate.
  22.                       This allows multiple indexes to be used.  In the past,
  23.                       the program assumed the index was pointing to the
  24.                       current record.  There is a sacrifice in update
  25.                       speed, however.
  26.  
  27.           18 Feb 92 - Fixed numerous problems with KeyFind and KeyUpdate.
  28.                       Corrected problem to ensure the first duplicate key
  29.                       is retrieved.  Corrected Index key insertion problem.
  30.  
  31.                       Added KeyBOF flag for test for access beyond top of
  32.                       file.
  33.  
  34.           19 Feb 92 - Embedded cache into Ndx_Get and Ndx_Put.  A number
  35.                       of node images will be stored to memory.  This will
  36.                       be treated as a stack, where the last page accessed
  37.                       will be pushed to the top and new nodes will use the
  38.                       bottom image.  They will replace the old image and
  39.                       push to the top.  This allows the most active nodes to
  40.                       remain in memory, with less active nodes being swapped
  41.                       out.  This also added a Ndx_Flush method to write all
  42.                       updated nodes to disk on demand, such as at closing.
  43.  
  44. ------------------------------------------------------------------------------}
  45.  
  46. interface
  47. {$D-}
  48.  
  49. uses
  50.    GS_Strng,                          {String handler routines}
  51.    GS_Error,                          {Error handler routines}
  52.    GS_FileH;                          {File handler routines}
  53.  
  54. const
  55.    NdxBufSize = 4096;
  56.    IndexSignature = 'NTX';
  57.    NdxBufferedPages = 16;
  58.  
  59. type
  60.  
  61. {
  62.          ┌──────────────────────────────────────────────────────────┐
  63.          │  ********      Index Header Description       ********   │
  64.          └──────────────────────────────────────────────────────────┘
  65. }
  66.    GS_Indx_Head = Record
  67.                      Vers1,
  68.                      Vers2       : Integer;
  69.                      Root        : Longint;
  70.                      Unknwn1     : Longint;
  71.                      Entry_Sz    : Integer;
  72.                      Key_Lgth    : Integer;
  73.                      Unknwn2     : Integer;
  74.                      Max_Keys    : Integer;
  75.                      Min_Keys    : Integer;
  76.                      Key_Form    : array [0..1001] of char;
  77.                   end;
  78.  
  79. {
  80.          ┌──────────────────────────────────────────────────────────┐
  81.          │  ********   Index Node Header Description     ********   │
  82.          └──────────────────────────────────────────────────────────┘
  83. }
  84.  
  85.    GS_Indx_Data = Record              {300 additional bytes for overflow}
  86.                      case integer of
  87.                         0 : (Data_Ary    : array [0..1323] of byte);
  88.                         1 : (Indx_Ary    : array [0..661] of word);
  89.                         2 : (Entry_Ct    : Integer);
  90.                   end;
  91.  
  92.    GS_Indx_EntPtr = ^GS_Indx_Etry;
  93.  
  94.  
  95. {
  96.          ┌──────────────────────────────────────────────────────────┐
  97.          │  ********   Index Node Key Entry Description   *******   │
  98.          └──────────────────────────────────────────────────────────┘
  99. }
  100.  
  101.    GS_Indx_Etry = Record
  102.                      Block_Ax : Longint;
  103.                      Recrd_Ax : Longint;
  104.                      Char_Fld : array [1..255] of char;
  105.                   end;
  106.  
  107.     GS_Indx_Tabl = Record
  108.                       Page_No  : Longint;   {Disk block holding node info}
  109.                       Etry_No  : Longint;   {Last entry used in node}
  110.                       Last_One : Longint;   {Number of keys in this node }
  111.                       Node_Pag : Boolean;   {True for non-leaf nodes}
  112.                    end;
  113.  
  114.    GS_Indx_LPtr = ^GS_dBase_IX;       {Pointer to object.  Used by GS_dBase_DB}
  115.  
  116.    GS_DiskPagPtr = ^GS_DiskPagBfr;
  117.    GS_DiskPagBfr = array[0..1023] of byte;
  118.  
  119.    GS_DiskTblPtr = ^GS_DiskTblPag;
  120.    GS_DiskTblPag = record
  121.       BlkNum : longint;
  122.       BlkWrt : boolean;
  123.       BlkPtr : GS_DiskPagPtr;
  124.    end;
  125.  
  126. {
  127.                       ┌─────────────────────────────────┐
  128.                       │  GS_dBase_IX Object Definition  │
  129.                       └─────────────────────────────────┘
  130. }
  131.  
  132.    GS_dBase_IX = object
  133.       Ndx_Name     : String[64];      {File name of index file}
  134.       Ndx_Hdr      : GS_Indx_Head;    {Index header information}
  135.       Ndx_File     : file;            {File type for index file}
  136.       Ndx_Tabl     : array [0..25] of GS_Indx_Tabl;
  137.                                       {Array of 25 table entries to hold}
  138.                                       {the trail of non-leaf nodes that are}
  139.                                       {traversed during a key search.  This }
  140.                                       {table is needed to track positions for}
  141.                                       {sequential reads (next and previous).}
  142.  
  143.       Ndx_Lvl      : integer;         {Holds counter into Ndx_Tabl}
  144.       Ndx_Data     : GS_Indx_Data;    {Node header information}
  145.       Ndx_Pntr     : GS_Indx_EntPtr;  {Pointer to key entry information}
  146.       Ndx_Key_St   : string[255];     {Holds last key value found on call to}
  147.                                       {either KeyRead or KeyFind}
  148.  
  149.       Ndx_Key_Num  : longint;         {Holds last physical record number for a}
  150.                                       {key value found on call to either}
  151.                                       {KeyRead or KeyFind}
  152.       Ndx_Key_Form : string[127];     {Holds the key formula in type string}
  153.       KeyBOF       : boolean;
  154.       KeyEOF       : boolean;         {True if last KeyRead attempted to read}
  155.                                       {beyond the range of index keys - either}
  156.                                       {beyond beginning or end of file}
  157.       ExactMatch   : boolean;         {Flag for type of test to use in KeyFind}
  158.                                       {It will force a match against an entire}
  159.                                       {key if true, and only for the length of}
  160.                                       {the passed argument if false.  It is}
  161.                                       {initialized true.}
  162.  
  163.       Ndx_PagArray : array[0..NdxBufferedPages-1] of GS_DiskTblPag;
  164.  
  165.       CONSTRUCTOR  Init(IName : String);
  166.       CONSTRUCTOR  Ndx_Make(filname,formla: string;lth: integer;typ: char);
  167.       DESTRUCTOR  Done;
  168.       FUNCTION  KeyFind(st : String) : longint;
  169.       FUNCTION  KeyLocRec(rec : longint) : boolean;
  170.       FUNCTION  KeyRead(a : LongInt) : longint;
  171.       PROCEDURE KeyUpdate (st : string; rec, crec : longint);
  172.       PROCEDURE Ndx_Close;
  173.       Procedure Ndx_Flush;
  174.       PROCEDURE Ndx_Get(blk : longint);
  175.       PROCEDURE Ndx_GetRecEntry;
  176.       PROCEDURE Ndx_GetRecPage(Ascnd : boolean);
  177.       FUNCTION  Ndx_LastEntry : boolean;
  178.       PROCEDURE Ndx_NodeData(pn, en, lo : longint; np : boolean);
  179.       PROCEDURE Ndx_Put(blk : longint);
  180.       Procedure KeyList(st : string);
  181.       FUNCTION  SetMatchValue(st : string): string;
  182.  
  183.  
  184.  
  185.    end;
  186. {.pa}
  187. {
  188.                          ┌──────────────────────────┐
  189.                          │  IMPLEMENTATION SECTION  │
  190.                          └──────────────────────────┘
  191. }
  192.  
  193. implementation
  194.  
  195.  
  196. const
  197.    Node_Size   = 1024; {Size of the node}
  198.  
  199.    Next_Record = -1;   {Token value passed to read next record}
  200.    Prev_Record = -2;   {T